package frontend.pages.admin.employee;

import backend.model.admin.CommuterData;
import backend.model.worklog.WorkLog;
import backend.service.admin.CommuterDataService;
import backend.service.worklog.WorkLogService;
import frontend.components.form.ButtonsBehavior;
import frontend.components.form.SaveDeleteButtonsPanel;
import frontend.core.TimeTrackingWebApplication;
import shared.util.CalendarUtils;
import frontend.components.other.UserInputCallableAction;
import org.apache.wicket.Localizer;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class CommuterDataListForm extends Form {

    private UserInputCallableAction refreshAction;

    public CommuterDataListForm(String id, List<CommuterData> commuterDataList, UserInputCallableAction refreshAction) {
        super(id);
        this.refreshAction = refreshAction;

        DefaultDataTable commuterDataTable = new DefaultDataTable<CommuterData>(
                "commuterDataTable", new CommuterDataTableTemplate().getColumns(), getTableDataProvider(commuterDataList), 3);
        add(commuterDataTable);
    }

    private void delete(CommuterData commuterData) {
        CommuterDataService commuterDataService = TimeTrackingWebApplication.getService(CommuterDataService.class);
        commuterDataService.deleteDBModel(commuterData);

        // Update work logs
        WorkLogService workLogService = TimeTrackingWebApplication.getService(WorkLogService.class);
        Collection<WorkLog> workLogs = workLogService.loadWorkLogForTimeIntervalAndEmployee(commuterData.getEmployee(), commuterData.getStartDate(), commuterData.getEndDate());
        for (WorkLog workLog : workLogs) {
            workLog.setIsCommuter(false);
        }
        workLogService.bulkSaveOrUpdateDBModels(workLogs);
    }

    private ISortableDataProvider<CommuterData> getTableDataProvider(final List<CommuterData> list) {

        ISortableDataProvider<CommuterData> dataProvider = new SortableDataProvider<CommuterData>() {
            @Override
            public Iterator<? extends CommuterData> iterator(int first, int count) {
                return list.subList(first, first+count).iterator();
            }

            @Override
            public int size() {
                return list.size();
            }

            @Override
            public IModel<CommuterData> model(final CommuterData entry) {
                return new LoadableDetachableModel<CommuterData>() {
                    @Override
                    protected CommuterData load() {
                        return entry;
                    }
                };
            }
        };
        return dataProvider;
    }

    class CommuterDataTableTemplate implements Serializable {

        private static final String RESOURCE_KEY_TABLE_HEADER_START_DATE = "table.header.startDate";
        private static final String RESOURCE_KEY_TABLE_HEADER_END_DATE = "table.header.endDate";

        protected List<IColumn<CommuterData>> columns = new LinkedList<IColumn<CommuterData>>();
        protected List<String> header = new LinkedList<String>();

        public CommuterDataTableTemplate() {
            createColumns();
        }

        public List<IColumn<CommuterData>> getColumns() {
            return columns;
        }

        public List<String> getHeader() {
            return header;
        }

        protected void createColumns() {
            createDefaultColumns();
        }

        private void createDefaultColumns() {
            columns.add(getStartDateColumn());
            columns.add(getEndDateColumn());
            columns.add(getActionColumn());
        }

        protected AbstractColumn<CommuterData> getStartDateColumn() {
            String columnName = Localizer.get().getString(RESOURCE_KEY_TABLE_HEADER_START_DATE, null);
            header.add(columnName);
            return new AbstractColumn<CommuterData>(new Model<String>(columnName), "startDate") {
                @Override
                public void populateItem(Item<ICellPopulator<CommuterData>> cellItem, String componentId, IModel<CommuterData> rowModel) {
                    CommuterData data = rowModel.getObject();
                    cellItem.add(new Label(componentId, CalendarUtils.formatDate(data.getStartDate())));
                }
            };
        }

        protected AbstractColumn<CommuterData> getEndDateColumn() {
            String columnName = Localizer.get().getString(RESOURCE_KEY_TABLE_HEADER_END_DATE, null);
            header.add(columnName);
            return new AbstractColumn<CommuterData>(new Model<String>(columnName), "endDate") {
                @Override
                public void populateItem(Item<ICellPopulator<CommuterData>> cellItem, String componentId, IModel<CommuterData> rowModel) {
                    CommuterData data = rowModel.getObject();
                    cellItem.add(new Label(componentId, CalendarUtils.formatDate(data.getEndDate())));
                }
            };
        }

        protected AbstractColumn<CommuterData> getActionColumn() {
            String columnName = "";
            header.add(columnName);
            return new AbstractColumn<CommuterData>(new Model<String>(columnName), "action") {
                @Override
                public void populateItem(Item<ICellPopulator<CommuterData>> cellItem, String componentId, final IModel<CommuterData> rowModel) {
                    CommuterData data = rowModel.getObject();
                    SaveDeleteButtonsPanel buttonsPanel = new SaveDeleteButtonsPanel(componentId,
                            new ButtonsBehavior() {
                                @Override
                                public void onSave(AjaxRequestTarget target) {
                                }

                                @Override
                                public void onDelete(AjaxRequestTarget target) {
                                    delete(rowModel.getObject());
                                    refreshAction.call(target, null);
                                }

                                @Override
                                public void onError(AjaxRequestTarget target) {
                                }

                                @Override
                                public boolean isDeleteButtonVisible() {
                                    return true;
                                }

                                @Override
                                public boolean isSaveButtonVisible() {
                                    return false;
                                }
                            });


                    cellItem.add(buttonsPanel);
                }
            };
        }


    }
}
